<template>
  <div class="condition-editor">
    <div class="editor-container">
      <div 
        ref="editorRef"
        class="editor-input"
        contenteditable="true"
        @input="handleInput"
        @keydown="handleKeydown"
        @click="handleClick"
        placeholder="请输入条件表达式，如：url 包含 'api' & method = 'GET'"
      ></div>
      
      <!-- 字段建议下拉框 -->
      <n-dropdown
        v-model:show="showSuggestions"
        :options="suggestionOptions"
        :x="dropdownX"
        :y="dropdownY"
        placement="bottom-start"
        @select="handleSelectSuggestion"
      />
    </div>
    
    <!-- 错误提示 -->
    <div v-if="error" class="error-message">
      <n-alert type="error" :show-icon="false">
        {{ error }}
      </n-alert>
    </div>
    
    <!-- 帮助提示 -->
    <div class="help-text">
      <n-text depth="3" size="small">
        支持字段：url, method, status, headers.*, params.*, cookies.*
        <br>
        运算符：=, !=, 包含, 不包含
        <br>
        逻辑：& (且), | (或), ! (非), () (分组)
      </n-text>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick, watch, onMounted } from 'vue';
import { NDropdown, NAlert, NText } from 'naive-ui';

interface Props {
  value: string;
}

interface Emits {
  (e: 'update:value', value: string): void;
  (e: 'error', error: string): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

// 组件状态
const editorRef = ref<HTMLElement>();
const showSuggestions = ref(false);
const dropdownX = ref(0);
const dropdownY = ref(0);
const currentInput = ref('');
const error = ref('');

// 可用字段建议
const fieldSuggestions = [
  'url',
  'method', 
  'status',
  'headers.content-type',
  'headers.user-agent',
  'headers.authorization',
  'params.id',
  'params.name',
  'cookies.session',
  'cookies.token'
];

// 运算符建议
const operatorSuggestions = [
  '=',
  '!=', 
  '包含',
  '不包含'
];

// 逻辑运算符
const logicOperators = ['&', '|', '!', '(', ')'];

// 建议选项
const suggestionOptions = ref<Array<{key: string, label: string}>>([]);

// 处理输入
const handleInput = (event: Event) => {
  const target = event.target as HTMLElement;
  const text = target.textContent || '';
  currentInput.value = text;
  emit('update:value', text);
  
  // 验证表达式
  validateExpression(text);
  
  // 检查是否需要显示建议
  checkForSuggestions(text);
};

// 处理键盘事件
const handleKeydown = (event: KeyboardEvent) => {
  const key = event.key;
  
  // 限制输入字符
  if (!isAllowedChar(key) && !isControlKey(key)) {
    event.preventDefault();
    return;
  }
  
  // 处理特殊键
  if (key === 'Enter' && showSuggestions.value) {
    event.preventDefault();
    // 选择第一个建议
    if (suggestionOptions.value.length > 0) {
      handleSelectSuggestion(suggestionOptions.value[0].key);
    }
  }
  
  if (key === 'Escape') {
    showSuggestions.value = false;
  }
};

// 处理点击
const handleClick = (event: MouseEvent) => {
  const rect = (event.target as HTMLElement).getBoundingClientRect();
  dropdownX.value = event.clientX;
  dropdownY.value = rect.bottom + 4;
};

// 检查字符是否允许输入
const isAllowedChar = (char: string): boolean => {
  // 允许字母、数字、空格、点、下划线、中文字符和特定符号
  const allowedPattern = /[a-zA-Z0-9\s._\u4e00-\u9fa5&|!()=]/;
  return allowedPattern.test(char) || ['包', '含', '不'].includes(char);
};

// 检查是否是控制键
const isControlKey = (key: string): boolean => {
  return ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 
          'Home', 'End', 'Tab', 'Enter', 'Escape'].includes(key);
};

// 检查是否需要显示建议
const checkForSuggestions = (text: string) => {
  const cursorPos = getCursorPosition();
  const beforeCursor = text.substring(0, cursorPos);
  const words = beforeCursor.split(/[\s&|!()=]/).filter(w => w.length > 0);
  const currentWord = words[words.length - 1] || '';
  
  if (currentWord.length >= 1) {
    // 搜索匹配的字段
    const matches = fieldSuggestions.filter(field => 
      field.toLowerCase().includes(currentWord.toLowerCase())
    );
    
    if (matches.length > 0) {
      suggestionOptions.value = matches.map(field => ({
        key: field,
        label: field
      }));
      showSuggestions.value = true;
      return;
    }
  }
  
  showSuggestions.value = false;
};

// 获取光标位置
const getCursorPosition = (): number => {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0) return 0;
  
  const range = selection.getRangeAt(0);
  const preCaretRange = range.cloneRange();
  preCaretRange.selectNodeContents(editorRef.value!);
  preCaretRange.setEnd(range.endContainer, range.endOffset);
  
  return preCaretRange.toString().length;
};

// 处理选择建议
const handleSelectSuggestion = (suggestion: string) => {
  const text = currentInput.value;
  const cursorPos = getCursorPosition();
  const beforeCursor = text.substring(0, cursorPos);
  const afterCursor = text.substring(cursorPos);
  
  // 替换当前单词
  const words = beforeCursor.split(/(\s|&|\||!|\(|\)|=)/);
  if (words.length > 0) {
    words[words.length - 1] = suggestion;
  }
  
  const newText = words.join('') + afterCursor;
  currentInput.value = newText;
  
  // 更新编辑器内容
  if (editorRef.value) {
    editorRef.value.textContent = newText;
  }
  
  emit('update:value', newText);
  showSuggestions.value = false;
  
  // 验证新表达式
  validateExpression(newText);
};

// 验证表达式
const validateExpression = (expression: string) => {
  if (!expression.trim()) {
    error.value = '';
    emit('error', '');
    return;
  }
  
  try {
    // 基本语法检查
    const tokens = tokenizeExpression(expression);
    const parseResult = parseTokens(tokens);
    
    if (parseResult.error) {
      error.value = parseResult.error;
      emit('error', parseResult.error);
    } else {
      error.value = '';
      emit('error', '');
    }
  } catch (e) {
    error.value = '表达式语法错误';
    emit('error', '表达式语法错误');
  }
};

// 表达式分词
const tokenizeExpression = (expression: string) => {
  const tokens: string[] = [];
  let current = '';
  let i = 0;
  
  while (i < expression.length) {
    const char = expression[i];
    
    if (char === ' ') {
      if (current) {
        tokens.push(current);
        current = '';
      }
    } else if (['&', '|', '!', '(', ')'].includes(char)) {
      if (current) {
        tokens.push(current);
        current = '';
      }
      tokens.push(char);
    } else if (char === '=' || (char === '!' && expression[i + 1] === '=')) {
      if (current) {
        tokens.push(current);
        current = '';
      }
      if (char === '!' && expression[i + 1] === '=') {
        tokens.push('!=');
        i++; // 跳过下一个字符
      } else {
        tokens.push(char);
      }
    } else {
      current += char;
    }
    i++;
  }
  
  if (current) {
    tokens.push(current);
  }
  
  return tokens.filter(token => token.trim());
};

// 解析tokens
const parseTokens = (tokens: string[]) => {
  // 简单的语法检查
  for (let i = 0; i < tokens.length; i++) {
    const token = tokens[i];
    
    // 检查字段名是否有效
    if (i % 4 === 0 && !['!', '('].includes(token)) {
      if (!isValidField(token)) {
        return { error: `未知字段: ${token}` };
      }
    }
    
    // 检查运算符是否有效
    if (i % 4 === 1 && !['=', '!=', '包含', '不包含'].includes(token)) {
      return { error: `无效运算符: ${token}` };
    }
    
    // 检查逻辑运算符
    if (i % 4 === 3 && !['&', '|', ')'].includes(token)) {
      return { error: `无效逻辑运算符: ${token}` };
    }
  }
  
  return { error: null };
};

// 检查字段是否有效
const isValidField = (field: string): boolean => {
  const validFields = ['url', 'method', 'status'];
  const validPrefixes = ['headers.', 'params.', 'cookies.'];
  
  return validFields.includes(field) || 
         validPrefixes.some(prefix => field.startsWith(prefix));
};

// 监听props变化
watch(() => props.value, (newValue) => {
  if (newValue !== currentInput.value) {
    currentInput.value = newValue;
    if (editorRef.value) {
      editorRef.value.textContent = newValue;
    }
    validateExpression(newValue);
  }
}, { immediate: true });

// 组件挂载后初始化
onMounted(() => {
  if (props.value && editorRef.value) {
    currentInput.value = props.value;
    editorRef.value.textContent = props.value;
  }
});
</script>

<style scoped>
.condition-editor {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.editor-container {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.editor-input {
  flex: 1;
  min-height: 120px;
  padding: 12px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--input-color);
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
  outline: none;
  transition: border-color 0.3s;
  overflow-y: auto;
}

.editor-input:focus {
  border-color: var(--primary-color);
}

.editor-input:empty::before {
  content: attr(placeholder);
  color: #888;
  pointer-events: none;
}

.error-message {
  margin-top: 8px;
  flex-shrink: 0;
}

.help-text {
  margin-top: 8px;
  padding: 8px;
  background: var(--info-color-suppl);
  border-radius: 4px;
  flex-shrink: 0;
}

/* 标签样式 */
.condition-tag {
  display: inline-block;
  padding: 2px 6px;
  margin: 0 2px;
  background: var(--primary-color-suppl);
  color: var(--primary-color);
  border-radius: 4px;
  font-size: 12px;
}

.operator-tag {
  display: inline-block;
  padding: 2px 6px;
  margin: 0 2px;
  background: var(--warning-color-suppl);
  color: var(--warning-color);
  border-radius: 4px;
  font-size: 12px;
}

.logic-tag {
  display: inline-block;
  padding: 2px 6px;
  margin: 0 2px;
  background: var(--success-color-suppl);
  color: var(--success-color);
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
}
</style> 